﻿namespace NullObjExpml
{
    using System;
    using System.Data.SqlTypes;

    /// <summary>
    /// Class which describes adress (soft null)
    /// </summary>
    public class Adress : IAssignable, INullable
    {
        #region Constructors

        public Adress()
            : this(0, string.Empty, string.Empty, string.Empty, 0)
        {
        }

        public Adress(int index, string country, string city, string street, int houseNumber)
        {
            m_Index = index;
            m_Country = country;
            m_City = city;
            m_Street = street;
            m_HouseNumber = houseNumber;
        }

        #endregion

        #region Properties

        public int Index
        {
            get { return m_Index; }
            set
            {
                if (!IsNull)
                    m_Index = value;
            }
        }

        public string Country
        {
            get { return m_Country; }
            set
            {
                if (!IsNull)
                    m_Country = value;
            }
        }

        public string City
        {
            get { return m_City; }
            set
            {
                if (!IsNull)
                    m_City = value;
            }
        }

        public string Street
        {
            get { return m_Street; }
            set
            {
                if (!IsNull)
                    m_Street = value;
            }
        }

        public int HouseNumber
        {
            get { return m_HouseNumber; }
            set
            {
                if (!IsNull)
                    m_HouseNumber = value;
            }
        }

        #endregion Properties

        #region IAssignable Implementation

        /// <summary>
        /// Content transfer
        /// </summary>
        /// <param name="obj">Object that takes content</param>
        /// <exception cref="ArgumentNullException">If object, that takes content is a null object </exception>
        /// <exception cref="NotSupportedException">If object, that takes content isn'tsupported by method</exception>
        /// <exception cref="InvalidOperationException">If current object is nullable</exception>
        public void AssignTo(object obj)
        {
            if (IsNull)
                throw new InvalidOperationException();

            if (obj == null)
                throw new ArgumentNullException();

            if (obj is Adress)
            {
                Adress a = obj as Adress;
                a.m_null = false;
                a.City = City;
                a.Country = Country;
                a.HouseNumber = HouseNumber;
                a.Index = Index;
                a.Street = Street;

                return;
            }

            throw new NotSupportedException();
        }

        #endregion

        #region INullable Implementation

        public bool IsNull
        {
            get { return m_null; }
        }

        public static Adress Null
        {
            get
            {
                Adress adr = new Adress();
                adr.m_null = true;
                return adr;
            }
        }

        #endregion

        #region Private Fields

        private bool m_null = false;
        private string m_Country = default(string);
        private string m_City = default(string);
        private string m_Street = default(string);
        private int m_Index = default(int);
        private int m_HouseNumber = default(int);

        #endregion
    }
}
